/*
 * Copyright (c) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup Pasteboard
 * @{
 *
 * @brief Provides APIs for copying and pasting multiple types of data,
 including plain text, HTML, URI, and pixel map.
 *
 * @since 13
 */

/**
 * @file oh_pasteboard.h
 *
 * @brief Provides data structs, enums, and APIs for accessing the system pasteboard.
 * File to include: <database/pasteboard/oh_pasteboard.h>
 *
 * @library libpasteboard.so
 * @syscap SystemCapability.MiscServices.Pasteboard
 *
 * @since 13
 */

#ifndef OH_PASTEBOARD_H
#define OH_PASTEBOARD_H

#include <inttypes.h>
#include <stdbool.h>
#include "database/udmf/udmf.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief Enumerates the data change types of the pasteboard.
 *
 * @since 13
 */
typedef enum Pasteboard_NotifyType {
    /**
     * @brief The pasteboard data of the local device is changed.
     */
    NOTIFY_LOCAL_DATA_CHANGE = 1,
    /**
     * @brief The pasteboard data of a non-local device on the network is changed.
     */
    NOTIFY_REMOTE_DATA_CHANGE = 2
} Pasteboard_NotifyType;

/**
 * @brief Called when the pasteboard content changes.
 *
 * @param context Pointer to the context information, which is passed by {@link OH_PasteboardObserver_SetData}.
 * @param type Type of the data change. For details, see {@link Pasteboard_NotifyType}.
 * @since 13
 */
typedef void (*Pasteboard_Notify)(void* context, Pasteboard_NotifyType type);

/**
 * @brief Called to release the context when the pasteboard observer object is destroyed.
 * @param context Pointer to the context to release.
 * @since 13
 */
typedef void (*Pasteboard_Finalize)(void* context);

/**
 * @brief Defines the pasteboard observer.
 *
 * @since 13
 */
typedef struct OH_PasteboardObserver OH_PasteboardObserver;

/**
 * @brief Creates a pointer to an {@link OH_PasteboardObserver} instance.
 *
 * @return Returns the pointer to the {@link OH_PasteboardObserver} instance created if the operation is successful;
 * returns a null pointer otherwise.
 * If this pointer is no longer required, use {@link OH_PasteboardObserver_Destroy} to destroy it.
 * Otherwise, memory leaks may occur.
 * @see OH_PasteboardObserver
 * @since 13
 */
OH_PasteboardObserver* OH_PasteboardObserver_Create();

/**
 * @brief Destroys an {@link OH_PasteboardObserver} instance.
 *
 * @param observer Pointer to the {@link OH_PasteboardObserver} instance to destroy.
 * @return Returns the error code. For details about the error codes, see {@link PASTEBOARD_ErrCode}.
 *         If {@link ERR_OK} is returned, the operation is successful.
 *         If {@link ERR_INVALID_PARAMETER} is returned, invalid parameters are specified.
 * @see OH_PasteboardObserver
 * @see PASTEBOARD_ErrCode
 * @since 13
 */
int OH_PasteboardObserver_Destroy(OH_PasteboardObserver* observer);

/**
 * @brief Sets callbacks for a pasteboard observer instance.
 *
 * @param observer Pointer to the {@link OH_PasteboardObserver} instance.
 * @param context Pointer to the context, which is passed to {@link Pasteboard_Notify} as the first parameter.
 * @param callback Callback for pasteboard data changes. For details, see {@link Pasteboard_Notify}.
 * @param finalize Callback to be invoked to release the context data when the pasteboard observer instance is
 * destroyed. For details, see {@link Pasteboard_Finalize}.
 * @return Returns the error code. For details about the error codes, see {@link PASTEBOARD_ErrCode}.
 *         If {@link ERR_OK} is returned, the operation is successful.
 *         If {@link ERR_INVALID_PARAMETER} is returned, invalid parameters are specified.
 * @see OH_PasteboardObserver
 * @see Pasteboard_Notify
 * @see PASTEBOARD_ErrCode
 * @since 13
 */
int OH_PasteboardObserver_SetData(OH_PasteboardObserver* observer, void* context,
    const Pasteboard_Notify callback, const Pasteboard_Finalize finalize);

/**
 * @brief Defines a pasteboard object, which is used for operating the system pasteboard.
 *
 * @since 13
 */
typedef struct OH_Pasteboard OH_Pasteboard;

/**
 * @brief Creates a pointer to an {@link OH_Pasteboard} instance.
 *
 * @return Returns a pointer to the {@link OH_Pasteboard} instance created if the operation is successful;
 * returns <b>nulllptr</b> otherwise.
 * @see OH_Pasteboard
 * @since 13
 */
OH_Pasteboard* OH_Pasteboard_Create();

/**
 * @brief Destroys an {@link OH_Pasteboard} instance.
 *
 * @param pasteboard Pointer to the {@link OH_Pasteboard} instance to destroy.
 * @see OH_Pasteboard
 * @since 13
 */
void OH_Pasteboard_Destroy(OH_Pasteboard* pasteboard);

/**
 * @brief Subscribes to pasteboard data changes.
 *
 * @param pasteboard Pointer to the {@link OH_Pasteboard} instance.
 * @param type Type of the data change. For details, see {@link Pasteboard_NotifyType}.
 * @param observer Pointer to the {@link OH_PasteboardObserver} instance.
 *                 It specifies the callback to be invoked when the pasteboard data changes. For details,
 * see {@link OH_PasteboardObserver}.
 * @return Returns the error code. For details about the error codes, see {@link PASTEBOARD_ErrCode}.
 *         If {@link ERR_OK} is returned, the operation is successful.
 *         If {@link ERR_INVALID_PARAMETER} is returned, invalid parameters are specified.
 * @see OH_Pasteboard
 * @see OH_PasteboardObserver
 * @see Pasteboard_NotifyType
 * @see PASTEBOARD_ErrCode
 * @since 13
 */
int OH_Pasteboard_Subscribe(OH_Pasteboard* pasteboard, int type, const OH_PasteboardObserver* observer);

/**
 * @brief Unsubscribes from pasteboard data changes.
 *
 * @param pasteboard Pointer to the {@link OH_Pasteboard} instance.
 * @param type Type of the data change. For details, see {@link Pasteboard_NotifyType}.
 * @param observer Pointer to the {@link OH_PasteboardObserver} instance to unregister.
 *                 It specifies the callback for pasteboard data changes. For details,
 * see {@link OH_PasteboardObserver}.
 * @return Returns the error code. For details about the error codes, see {@link PASTEBOARD_ErrCode}.
 *         If {@link ERR_OK} is returned, the operation is successful.
 *         If {@link ERR_INVALID_PARAMETER} is returned, invalid parameters are specified.
 * @see OH_Pasteboard
 * @see OH_PasteboardObserver
 * @see Pasteboard_NotifyType
 * @see PASTEBOARD_ErrCode
 * @since 13
 */
int OH_Pasteboard_Unsubscribe(OH_Pasteboard* pasteboard, int type, const OH_PasteboardObserver* observer);

/**
 * @brief Checks whether the pasteboard data is from a remote device.
 *
 * @param pasteboard Pointer to the {@link OH_Pasteboard} instance.
 * @return Returns a Boolean value indicating whether the data is from a remote device.
 * The value <b>true</b> means the data is from a remote device. The value <b>false</b> means the data is
 * from the local device.
 * @see OH_Pasteboard
 * @since 13
 */
bool OH_Pasteboard_IsRemoteData(OH_Pasteboard* pasteboard);

/**
 * @brief Obtains the pasteboard data source.
 *
 * @param pasteboard Pointer to the {@link OH_Pasteboard} instance.
 * @param source Pointer to the source of the pasteboard data obtained.
 * @param len Length of the data source string.
 * @return Returns the error code. For details about the error codes, see {@link PASTEBOARD_ErrCode}.
 *          If {@link ERR_OK} is returned, the operation is successful.
 *         If {@link ERR_INVALID_PARAMETER} is returned, invalid parameters are specified.
 * @see OH_Pasteboard
 * @see PASTEBOARD_ErrCode
 * @since 13
 */
int OH_Pasteboard_GetDataSource(OH_Pasteboard* pasteboard, char* source, unsigned int len);

/**
 * @brief Checks whether the pasteboard contains data of the specified type.
 *
 * @param pasteboard Pointer to the {@link OH_Pasteboard} instance.
 * @param type Pointer to the type of data to check.
 * @return Returns a Boolean value indicating whether the pasteboard contains data of the specified type.
 * The value <b>true</b> means the clipboard contains data of the specified type; the value false means the opposite.
 * @see OH_Pasteboard
 * @since 13
 */
bool OH_Pasteboard_HasType(OH_Pasteboard* pasteboard, const char* type);

/**
 * @brief Checks whether the pasteboard contains data.
 *
 * @param pasteboard Pointer to the {@link OH_Pasteboard} instance.
 * @return Returns a Boolean value indicating whether the pasteboard contains data.
 * The value <b>true</b> means the pasteboard contains data; the value <b>false</b> means the opposite.
 * @see OH_Pasteboard
 * @since 13
 */
bool OH_Pasteboard_HasData(OH_Pasteboard* pasteboard);

/**
 * @brief Obtains data from the pasteboard.
 *
 * @param pasteboard Pointer to the {@link OH_Pasteboard} instance.
 * @param status Pointer to the result obtained. For details about the error codes, see {@link PASTEBOARD_ErrCode}.
 * @return Returns the pointer to the {@link OH_UdmfData} instance obtained if the operation is successful;
 * returns <b>nullptr</b> otherwise.
 * @see OH_Pasteboard
 * @see OH_UdmfData
 * @see PASTEBOARD_ErrCode
 * @since 13
 */
OH_UdmfData* OH_Pasteboard_GetData(OH_Pasteboard* pasteboard, int* status);

/**
 * @brief Writes a unified data object to the pasteboard.
 *
 * @param pasteboard Pointer to the {@link OH_Pasteboard} instance.
 * @param data Pointer to the {@link OH_UdmfData} object to write.
 * @return Returns the error code. For details about the error codes, see {@link PASTEBOARD_ErrCode}.
 *          If {@link ERR_OK} is returned, the operation is successful.
 *         If {@link ERR_INVALID_PARAMETER} is returned, invalid parameters are specified.
 * @see OH_Pasteboard
 * @see OH_UdmfData
 * @see PASTEBOARD_ErrCode
 * @since 13
 */
int OH_Pasteboard_SetData(OH_Pasteboard* pasteboard, OH_UdmfData* data);

/**
 * @brief Clears data from the pasteboard.
 *
 * @param pasteboard Pointer to the {@link OH_Pasteboard} instance.
 * @return Returns the error code. For details about the error codes, see {@link PASTEBOARD_ErrCode}.
 *          If {@link ERR_OK} is returned, the operation is successful.
 *         If {@link ERR_INVALID_PARAMETER} is returned, invalid parameters are specified.
 * @see OH_Pasteboard
 * @see PASTEBOARD_ErrCode
 * @since 13
 */
int OH_Pasteboard_ClearData(OH_Pasteboard* pasteboard);

/**
 * @brief Obtains the MIME type from the pasteboard.
 *
 * @param pasteboard Pointer to the {@link OH_Pasteboard} instance.
 * @param count Pointer to the number of MIME types obtained.
 * @return Returns the MIME types obtained if the operation is successful; returns <b>nullptr</b> otherwise.
 * @see OH_Pasteboard.
 * @since 14
 */
char **OH_Pasteboard_GetMimeTypes(OH_Pasteboard *pasteboard, unsigned int *count);
#ifdef __cplusplus
};
#endif

/** @} */
#endif
